home *** CD-ROM | disk | FTP | other *** search
- ;*************************************************
- ;** Makros **
- ;** © 1990,93,96,98 THOR-Software inc. **
- ;** Version 1.18 vom 20.03.1998 **
- ;*************************************************
-
- ;*********************************
- ;** Globale Argumente: **
- ;** Falls das Label **
- ;** SHORTSTACK **
- ;** definiert ist, wird der **
- ;** Stack nur wordweise aligned **
- ;** ansonsten auf LW **
- ;*********************************
-
- ;*********************************
- ;** Einige Macros zum Setzen **
- ;** der CCR-Flags **
- ;** nach 6502-Manier **
- ;*********************************
- sec Macro ;C=1
- ori #$01,ccr
- Endm
-
- clc Macro ;C=0
- andi #$fe,ccr
- Endm
-
- sez Macro ;Z=1
- ori #$04,ccr
- Endm
-
- clz Macro ;Z=0
- andi #$fb,ccr
- Endm
-
- sen Macro ;N=1
- ori #$08,ccr
- Endm
-
- cln Macro ;N=0
- andi #$f7,ccr
- Endm
-
- noz Macro ;Z=NOT z
- eor #$04,ccr
- EndM
-
- sev Macro ;V=1
- ori #$02,ccr
- Endm
-
- clv Macro ;V=0
- andi #$fd,ccr
- Endm
-
- clx Macro ;X=0
- andi #$ef,ccr
- Endm
-
- sex Macro ;X=1
- ori #$10,ccr
- EndM
-
- ;*********************************
- ;** Löschen der verwendeten **
- ;** Zählvariablen **
- ;*********************************
-
- _sc set 0 ;unser StackCounter
- _rc set 0 ;Zähler für Registeraufgaben
- _re set 0 ;Ebenenzähler für Register
- _fc set 0 ;Zähler für Schleifen
- _fe set 0 ;Ebenenzähler für Schleifen
- _pc set 0 ;Parameterzähler für C-Prozeduren
- _pe set 0 ;Ebenenzähler für C-Prozeduren
- _pm set 0 ;Zählt entnommene Parameter
- _bs set 0 ;Größe des bss-Segmentes durch static
-
- ;*********************************
- ;** Einige Makros zur Stackver- **
- ;** waltung (für Variablen etc) **
- ;*********************************
-
- ifd __G2
-
- reserve Macro ;Platz auf dem Stack reservieren
- iflt \1
- fail ;Muß größer Null sein
- mexit
- endc
-
- ifd SHORTSTACK
- _si\<_sc> set (\1+((\1)&1))
- elseif
- _si\<_sc> set ((\1+3)&-4)
- endc
-
- ifne \1
- ifle _si\<_sc>-8
- subq.l #_si\<_sc>,a7
- elseif
- lea -_si\<_sc>(a7),a7
- endc
- endc
- _sc set _sc+1
- Endm
- ;Beispiel: reserve 100: 100 Bytes Platz sparen, a7 ist Baseregister
-
- restore Macro ;Platz auf dem Stack freigeben
- ifle _sc
- fail ;Nest-Fehler
- mexit
- endc
- _sc set _sc-1
- ifne _si\<_sc>
- ifle _si\<_sc>-8
- addq.l #_si\<_sc>,a7
- elseif
- lea _si\<_sc>(a7),a7
- endc
- endc
- EndM
- ;Beispiel: restore vorher reservierten Platz freigeben
-
- extend Macro ;Platz auf Speicher um n Bytes erweitern
- ifle _sc
- fail
- mexit ;Nest-Fehler
- endc
-
- ifd SHORTSTACK
- _si\<_sc> set (\1+((\1)&1))
- elseif
- _si\<_sc> set ((\1+3)&-4)
- endc
-
- ifle _si\<_sc>-8
- subq.l #_si\<_sc>,a7
- elseif
- lea -_si\<_sc>(a7),a7
- endc
- _sh set _sc-1
- _si\<_sh> set _si\<_sh>+_si\<_sc>
- EndM
- ;Beispiel: extend 50: 50 Bytes zum letzten zusätzlich dazuholen,a7=BasePtr
-
- shrink Macro ;Platz auf Speicher um n Bytes verringern
- ifle _sc
- fail ;Nest-Fehler
- mexit
- endc
-
- ifd SHORTSTACK
- _si\<_sc> set (\1+((\1)&1))
- elseif
- _si\<_sc> set ((\1+3)&-4)
- endc
-
- ifle _si\<_sc>-8
- addq.l #_si\<_sc>,a7
- elseif
- lea _si\<_sc>(a7),a7
- endc
- _sh set _sc-1
- _si\<_sh> set _si\<_sh>-_si\<_sc>
- iflt _si\<_sh>
- fail ;Range-Fehler
- mexit
- endc
- EndM
- ;Beispiel: shrink 50: 50 Bytes freigeben
-
- _lastget Macro ;Internes Macro zum Aufaddieren der Stacklängen
- ifne _sh-_sc
- _sj set _sj+_si\<_sh>
- _sh set _sh+1
- _lastget
- endc
- EndM
-
- loadbase Macro ;Basisadresse eines davorliegenden Base-Registers laden
- iflt \1
- fail ;Range-Fehler
- mexit
- endc
- _sh set _sc-\1
- iflt _sh
- fail ;Nest-Fehler
- mexit
- endc
-
- ifc '','\3'
- _sj set 0
- elseif
- _sj set \3
- endc
-
- _lastget
- lea _sj(a7),\2
- EndM
- ;Beispiel: loadbase 2,a6 Basisregister zum Speicherblock von vor zwei reserve-Befehlen zu a6
-
- saveregs Macro ;Register auf Stack sichern
- _rc set _rc+1 ;Anzahlzähler
- _re set _re+1 ;Ebenenzähler
- _rn\<_re> set _rc ;Ebene->Nummer
- _ri\<_rc> reg \1
- movem.l \1,-(sp)
- EndM
- ;Beispiel: saveregs d0-d1/a0-a1/a6
-
- loadregs Macro ;Register vom Stack holen
- ifle _re
- fail ;Nest-Fehler
- mexit
- endc
- _rt set _rn\<_re>
- movem.l (sp)+,_ri\<_rt>
- _re set _re-1
- EndM
- ;Beispiel: loadregs
-
- ;*********************************
- ;** Schleifenbefehle **
- ;*********************************
-
- for Macro ;Schleifenbeginn
- _fc set _fc+1 ;Anzahlzähler+1
- _fe set _fe+1 ;Ebenenzähler
- _fn\<_fe> set _fc ;Ebene->Nummer
- ifc '','\1' ;Ohne Parameter
- bra.\0 ._fi\<_fc>_loop
- elseif
- move.\0 \1-1,\2 ;Geht nur immediate
- endc
- ._fi\<_fc>_do:
- EndM
-
- ;Beispiele
- ; for :Schleifenbegin
- ; for.s :kurze Schleife
- ; for.l #9,d0 ;9 mal in d0
-
- next Macro ;Schleifenende
- ifle _fe
- fail ;Nest-Fehler
- mexit
- endc
- _ft set _fn\<_fe>
- ._fi\<_ft>_loop:
- ifc '','\1'
- fail ;Register fehlt
- mexit
- endc
- ifc '','\2'
- ._fi\<_ft>_cont:
- dbra \1,._fi\<_ft>_do
- elseif ;mit Bedingung cont nicht möglich
- db\1 \2,._fi\<_ft>_do
- endc
- ._fi\<_ft>_exit:
- _fe set _fe-1
- EndM
-
- ;Beispiele
- ; next d0
- ; next eq,d0 ;Abbrechen,wenn eq
-
- break Macro ;Schleife beenden
- ifle _fe
- fail ;break nicht im Schleifenrumpf
- mexit
- endc
- _ft set _fn\<_fe>
- ifc '','\1' ;ohne Bedingung
- bra.\0 ._fi\<_ft>_exit
- elseif
- b\1.\0 ._fi\<_ft>_exit
- endc
- EndM
-
- ;Beispiele
- ; break ;Abbrechen
- ; break.s
- ; break.s eq ;Abbrechen,wenn gleich
-
- cont Macro ;zum Next-Teil springen
- ifle _fe
- fail ;cont nicht im Schleifenrumpf
- mexit
- endc
- _ft set _fn\<_fe>
- ifc '','\1' ;ohne Bedingung
- bra.\0 ._fi\<_ft>_cont ;cont bei next mit Bedingung nicht möglich
- elseif
- b\1.\0 ._fi\<_ft>_cont ;cont bei next mit Bedingung nicht möglich
- endc
- EndM
-
- reloop Macro ;zum Schleifenanfang springen
- ifle _fe
- fail ;cont nicht im Schleifenrumpf
- mexit
- endc
- _ft set _fn\<_fe>
- ifc '','\1' ;ohne Bedingung
- bra.\0 ._fi\<_ft>_do
- elseif
- b\1.\0 ._fi\<_ft>_do
- endc
- EndM
- ;Beispiele
- ; reloop ;Schleife fortsetzen
- ; reloop.s
- ; reloop.s cc ;Abbrechen,wenn Carry gelöscht
-
- do Macro ;Schleife beginnen
- _fc set _fc+1 ;Anzahlzähler+1
- _fe set _fe+1 ;Ebenenzähler
- _fn\<_fe> set _fc ;Ebene->Nummer
- ._fi\<_fc>_do:
- ._fi\<_fc>_cont:
- EndM
- ;Schleifenbeginn
-
- repeat Macro ;Abweisende Schleife beginnen
- _fc set _fc+1 ;Anzahlzähler+1
- _fe set _fe+1 ;Ebenenzähler
- _fn\<_fe> set _fc ;Ebene->Nummer
- bra.\0 ._fi\<_fc>_loop ;Zum Schleifenende springen
- ._fi\<_fc>_do:
- ._fi\<_fc>_cont:
- EndM
-
- while Macro
- ifle _fe
- fail ;Nest-Fehler
- mexit
- endc
- _ft set _fn\<_fe>
- ._fi\<_ft>_loop:
- b\1.\0 ._fi\<_ft>_do
- ._fi\<_ft>_exit:
- _fe set _fe-1
- EndM
-
- loop Macro
- while.\0 ra
- EndM
-
- ;Beispiele
- ; do Wiederhole
- ; ...
- ; while.s eq solange =0
-
- ; repeat.s
- ; ...
- ; while.s eq dasselbe, nur wird nicht ausgeführt, falls schon beim Eintritt =0
- ;*********************************
- ;** String-Befehle **
- ;*********************************
-
- smove Macro
- ifne NARG-2
- fail ;nur zwei Parameter
- endc
-
- ._sm\@: move.b (\1)+,(\2)+
- bne.s ._sm\@
- EndM
-
- ;Beispiele
- ; smove a0,a1
- ; Kopiert String *a0 -> *a1
-
-
- strlen Macro
- ifne NARG-2
- fail ;nur zwei Parameter
- mexit
- endc
- move.l \1,\2
- ._sl\@:
- tst.b (\1)+
- bne.s ._sl\@
- sub.l \1,\2
- not.l \2
- Endm
-
- ;Beispiele
- ; strlen a0,d0
- ; Holt Länge des Strings a0 zu d0
- ; a0 zeigt danach auf das Stringende (das NUL-Byte)
-
-
- ;*********************************
- ;** C-Prozedurbefehle **
- ;*********************************
-
- _putarg Macro ;Zum Schreiben eines Argumentes
- ifgt \1
- _pm set 1 ;Ein Parameter entnommen
-
- ifnc '','\2'
- ;hier: Parameter vorhanden
- ifc '.l','\2'
- _pm set 2 ;mit Angabe: Longword
- _pc set _pc+4
- endc
- ifc '.w','\2'
- _pm set 2 ;mit Angabe: Word
- _pc set _pc+2
- endc
- ifc '.b','\2'
- _pm set 2 ;mit Angabe: Byte
- _pc set _pc+2 ;ja: ein Byte benötigt zwei Bytes (strange, what ?)
- endc
-
- ifeq _pm-2
- ifc '\3',''
- fail ;Parameter fehlt
- mexit
- endc
- move\2 \3,-(sp) ;hier mit Angabe
- elseif
- ifne _fl
- move.l \2,-(sp) ;Long
- _pc set _pc+4
- elseif
- move.w \2,-(sp) ;oder hier mit ohne: Word
- _pc set _pc+2
- endc
- endc
-
- endc
-
-
- _pe set \1-_pm
- ifeq _pm-2
- _putarg \<_pe>,\4,\5,\6,\7,\8,\9,\A,\B,\C,\D,\E,\F,\G,\H,\I,\J
- elseif
- _putarg \<_pe>,\3,\4,\5,\6,\7,\8,\9,\A,\B,\C,\D,\E,\F,\G,\H,\I,\J
- endc
-
- endc
- endm
-
-
- bcr Macro ;Aufruf mit bsr
- _pc set 0
- _fl set 0
- _putarg 18,\J,\I,\H,\G,\F,\E,\D,\C,\B,\A,\9,\8,\7,\6,\5,\4,\3,\2
- bsr.\0 \1
- ifne _pc
- lea _pc(a7),a7
- endc
- EndM
-
- jcr Macro ;Aufruf mit jsr
- _pc set 0
- _fl set 0
- _putarg 18,\J,\I,\H,\G,\F,\E,\D,\C,\B,\A,\9,\8,\7,\6,\5,\4,\3,\2
- jsr \1
- ifne _pc
- lea _pc(a7),a7
- endc
- EndM
-
- jtags Macro ;Aufruf einer Library mit Tags
- _pc set 4
- _fl set 1
- clr.l -(a7) ;TAG_END
- _putarg 17,\J,\I,\H,\G,\F,\E,\D,\C,\B,\A,\9,\8,\7,\6,\5,\4,\3
- move.l a7,\2
- jsr \1
- lea _pc(a7),a7
- EndM
-
-
- ;Beispiele:
- ;jcr Handler,.l,#0,IO(a1)
- ;bcr.s TempFree,a1,.l,a5,.l,#0,.b,Execbase,.l
- ;
- ;Defaultgröße ist Word
- ;Alles mit bis zu 18(17) Parametern,eventuell Typenangabe möglich (sonst Überlauf der Macro-Ebenen)
- ;Bei tags generell alles long !
-
- deftag Macro ;Beginn eines Tag-Aufrufes
- _pc set 4
- clr.l -(a7) ;TAG_END
- EndM
-
- tag Macro
- move.l \2,-(sp) ;illegale Tagdaten
- move.l #\1,-(sp) ;illegale Tagdaten
- _pc set _pc+8
- EndM
-
- itag Macro
- move.l \2,-(sp) ;illegale Tagdaten
- move.l \1,-(sp) ;illegale Tagdaten
- _pc set _pc+8
- EndM
-
- endtag Macro ;Ende eines Tag-Aufrufes
- move.l a7,\2
- jsr \1
- lea _pc(a7),a7
- endM
-
- ;Beispiele:
- ;deftag
- ; tag FT+3,Size
- ;endtag OpenWindowTagList(a6),a0
-
- defarg Macro ;Start der Argumentendefinition
- rsreset
- _sh set 0
- _sj set 0
- _lastget
- rs.l 1 ;für PC reserviert
- ifnc '','\1'
- rs.l \1 ;Angabe der # geretteter Register
- endc
- rs.b _sj ;Soviel für Variablen etc. reserviert
- EndM
-
- arg Macro ;Name eines Argumentes bestimmen
- ifc '','\0'
- \1 rs.w 1
- elseif
- \1 rs.\0 1
- ifc 'b','\0'
- rs.b 1
- endc
- endc
- EndM
-
- endarg Macro
- ;Dummy-Makro
- EndM
-
- ;Beispiele
- ; defarg Beginn der Argumentendefinition
- ; arg Buffer Ein Argument, keine Größe => also Word
- ; arg.l Code Ein LW
- ; arg.w Len Ein Word
- ; arg.b char Ein Byte
- ; endarg Ende der Definition
-
- ; Noch ein Sonderservice: Unsere=C Arg-Convention ist bis auf aufeinanderfolgende
- ; Byte-Variablen kompatibel zur Auto-Variablen Deklaration (s.u.)
- ;*********************************
- ;** Variablenbefehle **
- ;*********************************
- defvar Macro
- rsreset
- EndM ;Start der Variablen-Deklaration
- auto Macro
- ifc '','\2'
- \1 rs.\0 1
- elseif
- \1 rs.\0 \2
- endc
- EndM ;Eine Variable auf dem Stack,Array erlaubt
-
- static Macro
- ifc '','\2'
- _bc set 1
- elseif
- _bc set \2
- endc
- _bz set 0
- ifc 'l','\0'
- _bs set (_bs+1)&$fffffffe
- _bz set 4
- endc
- ifc 'w','\0'
- _bs set (_bs+1)&$fffffffe
- _bz set 2
- endc
- ifc 'b','\0'
- _bz set 1
- endc
- ifeq _bz
- fail ;unbekannte Datengröße
- mexit
- endc
- \1 =_bs
- _bs set _bs+(_bc*_bz)
- EndM ;Eine Variable im bss, Array erlaubt
-
- extern Macro
- xref \1
- EndM ;Eine externe Variable
- register Macro
- \1 equr \2
- EndM ;Eine Register-Variable
- endvar Macro
- ._vl\@ rs.b 0
- reserve ._vl\@
- EndM ;Ende einer Variablenliste
-
- freevar Macro ;Variablen freigeben
- restore
- EndM
- staticspace Macro
- ds.b _bs ;Platz für static reservieren
- EndM
-
- ; defvar Ein Beispiel:
- ; auto.w count eine Wordvariable
- ; auto.l help,4 ein LongWord-Array (4 Stück)
- ; auto.b char eine Byte-Variable
- ; auto.l inc eine longword-Variable
- ; static.l save eine statische Variable (alles global)
- ; register.w cinc,d0 eine Register-Variable (alles global)
- ; endvar
- ; restore=freevar vor Verlassen des Unterprogrammes zum Wiederherstellen des SP nicht vergessen !
- ; (Nur wenn auto-Variablen vorhanden)
-
- endc
-
- ;*********************************
- ;** Langwort-Bit-Befehle **
- ;** für d(an) Adressiermodus **
- ;** und Absolut,d(an,dn) **
- ;*********************************
- btstm Macro
- btst #(\1)&$7,(3^((\1)>>3))+\2
- Endm
-
- bclrm Macro
- bclr #(\1)&$7,(3^((\1)>>3))+\2
- Endm
-
- bsetm Macro
- bset #(\1)&$7,(3^((\1)>>3))+\2
- Endm
-
- bchgm Macro
- bchg #(\1)&$7,(3^((\1)>>3))+\2
- Endm
-
- ;Umkehrung zu btstm
-
- bnegm Macro
- btst #(\1)&$7,(3^((\1)>>3))+\2
- noz
- Endm
-
- ;Beispiel: btstm 21,10(a5) ;Bit 21 im LW 10(a5) testen
-
-
- ;*************************************************
- ;** Listenverarbeitungsmakros **
- ;*************************************************
-
- ;Liste vorbereiten: Argument ist Ptr
- NewList Macro
- move.l \1,8(\1)
- addq.l #4,\1
- clr.l (\1)
- move.l \1,-(\1)
- endm
-
- ;*a1 an Liste *a0 anhängen (Aufruf wie Exec-Routine)
- AddHead Macro
- MOVE.L (A0),D0
- MOVE.L A1,(A0)
- MOVEM.L D0/A0,(A1)
- MOVE.L D0,A0
- MOVE.L A1,4(A0)
- ENDM
-
- ;*a1 an Liste *a0 anhängen (Aufruf wie Exec-Routine)
- AddTail Macro
- ADDQ.L #4,A0
- MOVE.L 4(A0),D0
- MOVE.L A1,4(A0)
- EXG D0,A0
- MOVEM.L D0/A0,(A1)
- MOVE.L A1,(A0)
- ENDM
-
- ;*a1 entfernen (Aufruf wie Exec-Routine)
- Remove Macro
- MOVE.L (A1)+,A0
- MOVE.L (A1),A1
- MOVE.L A0,(A1)
- MOVE.L A1,4(A0)
- ENDM
-
- ;Entferne eine Node von *a0 (Aufruf wie Exec-Routine)
- RemHead Macro
- MOVE.L (A0),A1
- MOVE.L (A1),D0
- BEQ.S .__remhead\@
- MOVE.L D0,(A0)
- EXG.L D0,A1
- MOVE.L A0,4(A1)
- .__remhead\@:
- ENDM
-
-
- ;Entferne eine Node von *a0 (Aufruf wie Exec-Routine)
- RemTail Macro
- MOVE.L 8(A0),A1
- MOVE.L 4(A1),D0
- BEQ.S .__remtail\@
- MOVE.L D0,8(A0)
- EXG.L D0,A1
- MOVE.L A0,(A1)
- ADDQ.L #4,(A1)
- .__remtail\@:
- ENDM
-
-
- ;InsertAfter: Node *a1 hinter Node *a0 einhängen. (Keine Spezialfälle)
- InsertAfter Macro
- move.l (a0),d0
- movem.l d0/a0,(a1)
- move.l a1,(a0)
- move.l d0,a0
- move.l a1,4(a0)
- EndM
-
- ;InsertBefore Node *a1 vor Node *a0 einhängen. (Keine Spezialfälle)
- InsertBefore Macro
- move.l 4(a0),d0
- move.l a1,4(a0)
- exg.l a0,d0
- movem.l d0/a0,(a1)
- move.l a1,(a0)
- EndM
-
-
-